unit uCalculaFrete;

interface

uses
  SysUtils, Classes, IdHttp;

type
    TCFValorFrete = class(TComponent)
    private

    protected
        vValor: Currency;
        vPrazoEntrega: Integer;
        vValorMaoPropria: Currency;
        vValorAvisoRecebimento: Currency;
        vValorDeclarado: Currency;
        vEntregaDomicilio: Boolean;
        vEntregaSabado: Boolean;
        vErro: String;
        vMsgErro: String;

    public
        Codigo: Integer;
        Constructor Create(Aowner: TComponent); override;
        destructor Destroy ; override ;
    published
        property Valor: Currency read vValor write vValor;
        property PrazoEntrega: Integer read vPrazoEntrega write vPrazoEntrega;
        property ValorMaoPropria: Currency read vValorMaoPropria write vValorMaoPropria;
        property ValorAvisoRecebimento: Currency read vValorAvisoRecebimento write vValorAvisoRecebimento;
        property ValorDeclarado: Currency read vValorDeclarado write vValorDeclarado;
        property EntregaDomiciliar: Boolean read vEntregaDomicilio write vEntregaDomicilio;
        property EntregaSabado: Boolean read vEntregaSabado write vEntregaSabado;
        property Erro: String read vErro write vErro;
        property MsgErro: String read vMsgErro write vMsgErro;


    end;


    TCFFormato = (cffCaixaPacote,cffRoloPrisma,cffEnvelope) ;

  //Componente Calcula Frete
  TCalculaFrete = class(TComponent)
  private
    vCepOrigem : String;
    vCepDestino : String;
    vVlPeso: Double;
    vFormato: TCFFormato;
    vVlComprimento: Double;
    vVlAltura : Double;
    vVlLargura  :  Double;
    vVlValorDeclarado : Currency;
    vCdAvisoRecebimento : boolean;
    vCdMaoPropria : boolean;
    vVlDiametro : Double;

    vPac: TCFValorFrete;
    vSedex: TCFValorFrete;
    vSedex10: TCFValorFrete;
  protected
    { Protected declarations }
  public
    retorno, url: String;
    Constructor Create (Aowner: TComponent); override;
    Destructor Destroy ; override ;
    procedure GetValores;
    procedure SetValores(vv : TCFValorFrete);
    function ValoresAsString: String;

  published
    property Pac: TCFValorFrete read vPac write vPac;
    property Sedex: TCFValorFrete read vSedex write vSedex;
    property Sedex10: TCFValorFrete read vSedex10 write vSedex10;
    property CepOrigem : String read vCepOrigem  write vCepOrigem;
    property CepDestino : String read vCepDestino  write vCepDestino;
    property CaixaPeso: Double read vVlPeso write vVlPeso;
    property Formato: TCFFormato read vFormato write vFormato ;
    property CaixaComprimento: Double read vVlComprimento write vVlComprimento ;
    property CaixaAltura : Double read vVlAltura write vVlAltura ;
    property CaixaLargura  :  Double read vVlLargura  write vVlLargura;
    property ValorDeclarado : Currency read vVlValorDeclarado write vVlValorDeclarado ;
    property EntregaComAvisoRecebimento : boolean read vCdAvisoRecebimento write vCdAvisoRecebimento ;
    property EntregaMaoPropria : boolean read vCdMaoPropria write vCdMaoPropria ;
    property CaixaDiametro : Double read vVlDiametro write vVlDiametro;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MRSoftware', [TCalculaFrete]);
end;

{ TCFValorFrete }

constructor TCFValorFrete.Create(Aowner: TComponent);
begin
    inherited create(Aowner);
    vValor:= 0;
    vPrazoEntrega:= 0;
    vValorMaoPropria:= 0;
    vValorAvisoRecebimento:= 0;
    vValorDeclarado:= 0;
    vEntregaDomicilio:= false;
    vEntregaSabado:= false;
    vErro:= '';
    vMsgErro:= '';

end;

destructor TCFValorFrete.Destroy;
begin

    inherited;
end;

{ TCalculaFrete }

constructor TCalculaFrete.Create(Aowner: TComponent);
begin
    inherited create(Aowner);
    VPac := TCFValorFrete.Create(self);
    vPac.Codigo := 41106;
    VPAC.Name := 'PAC';
    VPac.SetSubComponent(true);

    vSedex := TCFValorFrete.Create(self);
    vSedex.Codigo := 40010;
    vSedex.Name := 'Sedex';
    vSedex.SetSubComponent(true);

    vSedex10 := TCFValorFrete.Create(self);
    vSedex10.Codigo := 40215;
    vSedex10.Name := 'Sedex10';
    vSedex10.SetSubComponent(true);

end;

destructor TCalculaFrete.Destroy;
begin
  vPac.Free;
  vSedex.Free;
  vSedex10.Free;
  inherited;
end;

procedure TCalculaFrete.GetValores;
var
    Requisicao: TIdHttp;
    DecSeparTemp: Char;
    vvFormato: String;
    vvMaoPropria, vvAvisoRec: String;

begin
    case cffCaixaPacote of
        cffCaixaPacote: vvFormato := '1';
        cffRoloPrisma: vvFormato := '2';
        cffEnvelope: vvFormato := '3';
    end;

    if vCdAvisoRecebimento then vvAvisoRec := 'S' else vvAvisoRec := 'N';
    if vCdMaoPropria then vvMaoPropria := 'S' else vvMaoPropria := 'N';

    //DecSeparTemp := DecimalSeparator;
    //DecimalSeparator := ',';
    Requisicao := TIdHTTP.Create(self);
    url := 'http://ws.correios.com.br/calculador/'+
        'CalcPrecoPrazo.aspx'+
        '?nCdEmpresa=&sDsSenha='+
        '&sCepOrigem='+ vCepOrigem +
        '&sCepDestino='+vCepDestino+
        '&nVlPeso='+FloatToStr(vVlPeso)+
        '&nCdFormato='+vvFormato+
        '&nVlComprimento='+FloatToStr(vVlComprimento) +
        '&nVlAltura='+FloatToStr(vVlComprimento) +
        '&nVlLargura='+FloatToStr(vVlLargura) +
        '&sCdMaoPropria='+vvMaoPropria+
        '&nVlValorDeclarado='+FloatToStr(vVlValorDeclarado) +
        '&sCdAvisoRecebimento='+vvAvisoRec+
        '&nCdServico=40010,40215,41106'+
        '&nVlDiametro='+FloatToStr(vVlDiametro) +
        '&StrRetorno=xml&randomize='+
        FormatDateTime('yymmddhhnnss',now)+inttostr(random(999999999))
    ;

    retorno := Requisicao.Get(url);
    SetValores(vPac);
    SetValores(vSedex);
    SetValores(vSedex10);
    //DecimalSeparator := DecSeparTemp;

end;

procedure TCalculaFrete.SetValores(vv: TCFValorFrete);
var
    booltemp, strtemp, sIniTemp, sFimTemp: String;
    pini, pfim: integer;
    DecSeparTemp: Char;
begin
    //DecSeparTemp := DecimalSeparator;
    //DecimalSeparator := ',';
    pini := pos('<Codigo>'+IntToStr(vv.Codigo)+'</Codigo>', retorno);
    strtemp := copy(retorno,pini,length(retorno) - pini);

    sIniTemp := '<Valor>'; sFimTemp := '</Valor>';
    pini := pos(sIniTemp,strtemp) + length(sIniTemp); pFim := pos(sFimTemp, strtemp) - pini;
    vv.Valor := StrToFloat(copy(strtemp,pini,pfim));

    sIniTemp := '<PrazoEntrega>'; sFimTemp := '</PrazoEntrega>';
    pini := pos(sIniTemp,strtemp) + length(sIniTemp); pFim := pos(sFimTemp, strtemp) - pini;
    vv.PrazoEntrega := StrToInt(copy(strtemp,pini,pfim));

    sIniTemp := '<ValorMaoPropria>'; sFimTemp := '</ValorMaoPropria>';
    pini := pos(sIniTemp,strtemp) + length(sIniTemp); pFim := pos(sFimTemp, strtemp) - pini;
    vv.ValorMaoPropria := StrToFloat(copy(strtemp,pini,pfim));

    sIniTemp := '<ValorAvisoRecebimento>'; sFimTemp := '</ValorAvisoRecebimento>';
    pini := pos(sIniTemp,strtemp) + length(sIniTemp); pFim := pos(sFimTemp, strtemp) - pini;
    vv.ValorMaoPropria := StrToFloat(copy(strtemp,pini,pfim));

    sIniTemp := '<ValorValorDeclarado>'; sFimTemp := '</ValorValorDeclarado>';
    pini := pos(sIniTemp,strtemp) + length(sIniTemp); pFim := pos(sFimTemp, strtemp) - pini;
    vv.ValorDeclarado := StrToFloat(copy(strtemp,pini,pfim));

    sIniTemp := '<EntregaDomiciliar>'; sFimTemp := '</EntregaDomiciliar>';
    pini := pos(sIniTemp,strtemp) + length(sIniTemp); pFim := pos(sFimTemp, strtemp) - pini;
    booltemp := copy(strtemp,pini,pfim);
    if booltemp = 'S' then vv.EntregaDomiciliar := true else vv.EntregaDomiciliar := false;

    sIniTemp := '<EntregaSabado>'; sFimTemp := '</EntregaSabado>';
    pini := pos(sIniTemp,strtemp) + length(sIniTemp); pFim := pos(sFimTemp, strtemp) - pini;
    booltemp := copy(strtemp,pini,pfim);
    if booltemp = 'S' then vv.EntregaSabado := true else vv.EntregaSabado := false;

    sIniTemp := '<Erro>'; sFimTemp := '</Erro>';
    pini := pos(sIniTemp,strtemp) + length(sIniTemp); pFim := pos(sFimTemp, strtemp) - pini;
    vv.Erro := copy(strtemp,pini,pfim);

    if vv.Erro <> '0' then
    begin
        sIniTemp := '<MsgErro>'; sFimTemp := '</MsgErro>';
        pini := pos(sIniTemp,strtemp) + length(sIniTemp); pFim := pos(sFimTemp, strtemp) - pini;
        vv.MsgErro := copy(strtemp,pini,pfim);
    end else
    begin
        vv.MsgErro := '';
    end;


    //DecimalSeparator := DecSeparTemp;

end;

function TCalculaFrete.ValoresAsString: String;
var
    retorno: STring;
begin
    retorno := 'PAC: ' + FormatFloat('0.00',vPac.vValor)+#10#13+
        'SEDEX: ' + FormatFloat('0.00',vSedex.vValor)+#10#13+
        'SEDEX 10: ' + FormatFloat('0.00',vSedex10.vValor)+#10#13
    ;
    result := retorno;
end;

end.
